var _ = require('lodash'),
    Q = require('q'),
    QCEnum = require('../../../QC/server/controllers/Enum.server.controller'),
    BarcodeEnum = require('../../../Barcode/server/controllers/Enum.server.controller'),
    barcodeMasterController = require('../../../Barcode/server/controllers/BarcodeMaster.server.controller'),
    qcRecordController = require('../../../QC/server/controllers/QCRecord.server.controller'),
    extendEnumController = require('../../../SystemManage/server/controllers/ExtendEnum.server.controller'),
    userController = require('../../../User/server/controllers/users.server.controller'),
    terminalController = require('../../../CBO/server/controllers/Terminal.server.controller'),
    bizRecordController = require('../../../Barcode/server/controllers/BizRecord.server.controller');

exports.specialScanCode = function(req, res) {
    var parameter = req.body.Parameter,
        barcode = parameter.Barcode;

    doScanCode(barcode, '107').then(function (result) {
        res.json(result);
    }, function (err) {
        res.json(err);
    });
};

exports.getBadMasters = function(req, res) {
    barcodeMasterController.findBadMasters(function (err, records) {
        if (err) {
            res.json({
                Data: null,
                Error: err
            });
            return;
        }
        res.json({
            Data: records,
            Error: null
        });
    });
};

exports.doJudge = function(req, res) {
    var parameter = req.body.Parameter,
        barcode = parameter.Barcode,
        terminalUniqueID = parameter.TerminalUniqueID,
        userId = parameter.UserID,
        QCStatus = parameter.QCStatus,
        Remark = parameter.Remark;
 
    var dateNow = Date.now(),
        bizRecord = {
            CollectDateTime: dateNow,
            BusinessStatus: 1,
            Users: [userId],
            QCUser: userId,
            QCDateTime: dateNow,
            QCStatus: QCStatus,
            Remark: Remark
        };
    queryBarcodeMaster(barcode).then(function (barcodeMasterRecord) {
        bizRecord.BarcodeMaster = barcodeMasterRecord._id;
        bizRecord.Work = barcodeMasterRecord.Work._id;
        bizRecord.WorkName = barcodeMasterRecord.Work.Name;
        bizRecord.WorkLocation = barcodeMasterRecord.WorkLocation;
        bizRecord.WorkLocationName = barcodeMasterRecord.WorkLocationName;
        bizRecord.Operation = barcodeMasterRecord.Operation._id;
        bizRecord.OperationName = barcodeMasterRecord.Operation.Name;
        bizRecord.QCType = barcodeMasterRecord.QCType;
        return queryHardwareInfo(terminalUniqueID);
    }).then(function (hardwareInfo) {
        _.merge(bizRecord, hardwareInfo);
        return writebizRecord(barcode, bizRecord);
    }).then(function () {
        res.json({
            Data: true,
            Error: null
        });
    }).catch(function (err) {
        res.json({
            Data: null,
            Error: err
        });
    })
    .done();
};

exports.decideScanCode = function(req, res) {
    var parameter = req.body.Parameter,
        barcode = parameter.Barcode;

    doScanCode(barcode, '109').then(function (result) {
        res.json(result);
    }, function (err) {
        res.json(err);
    });
};

function doScanCode (barcode, requiredRole) {
    var deferred = Q.defer();

    queryBarcodeMaster(barcode).then(function (barcodeMasterRecord) {
        if (barcodeMasterRecord.BarcodeType === BarcodeEnum.BarcodeType.ItemMaster) {
            return queryMasterInfo(barcodeMasterRecord);
        } else if (barcodeMasterRecord.BarcodeType === BarcodeEnum.BarcodeType.Person) {
            return queryUserInfo(barcodeMasterRecord.EntityID, requiredRole);
        } else {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '无法识别条码';
            newErr.message = '无法识别的条码，请重新扫描！';
            return Q.when({
                Data: null,
                Error: newErr
            });
        }
    }).then(function (result) {
        deferred.resolve(result);
    }).catch(function (err) {
        deferred.reject(err);
    })
    .done();

    return deferred.promise;
}

function queryBarcodeMaster (barcode) {
    var deferred = Q.defer();
    
    barcodeMasterController.findBarcodeMaster(barcode, function (err, barcodeMasterRecord) {
        if (err) {
            deferred.reject(err);
            return;
        }
        if (barcodeMasterRecord == null) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '条码扫描失败';
            newErr.message = '该条码没有对应的条码主档！';
            deferred.resolve({
                Data: null,
                Error: newErr
            });
        }
        deferred.resolve(barcodeMasterRecord);
    });

    return deferred.promise;
}

function queryMasterInfo (barcodeMaster) {
    var deferred = Q.defer();

    if (barcodeMaster.QCStatus !== QCEnum.QCStatus.NotQualified) {
        var newErr = new Error();
        newErr.leval = 9;
        newErr.message = '物品' + barcodeMaster.ItemMasterCode;
        if (barcodeMaster.QCStatus) {
            newErr.message += '，当前质检状态为';
            if (barcodeMaster.QCStatus == QCEnum.QCStatus.Qualified) {
                newErr.message += '合格';
            } else if (barcodeMaster.QCStatus == QCEnum.QCStatus.Concession) {
                newErr.message += '让步接收';
            } else if (barcodeMaster.QCStatus == QCEnum.QCStatus.Decide) {
                newErr.message += '品质判定';
            } else if (barcodeMaster.QCStatus == QCEnum.QCStatus.Rework) {
                newErr.message += '返工';
            } else if (barcodeMaster.QCStatus == QCEnum.QCStatus.Scrap) {
                newErr.message += '报废';
            }
        } else {
            newErr.message += '，当前还没有进行过质检';
        }    
        newErr.message += '，无需特裁！';
        deferred.resolve({
            Data: null,
            Error: newErr
        });
    } else {
        var result = {
            BarcodeType: barcodeMaster.BarcodeType,
            MOCode: barcodeMaster.MOCode,
            WorkName: barcodeMaster.WorkName,
            MOLotNumber: barcodeMaster.MOLotNumber,
            Specification: barcodeMaster.ItemMaster.Specification,
            ItemMasterCode: barcodeMaster.ItemMasterCode,
            ItemMasterName: barcodeMaster.ItemMasterName,
            Users: barcodeMaster.Users
        };
        if (barcodeMaster.BizRecord) {
            result.Remark = barcodeMaster.BizRecord.Remark;
        }
        qcRecordController.findQCRecords(barcodeMaster.BizRecord._id, function (err, qcRecords) {
            if (err) {
                deferred.resolve({
                    Data: null,
                    Error: err
                });
                return;
            }
            var enumOptions = {};
            Q.all([
                queryExtendEnumOption('BadType', enumOptions),
                queryExtendEnumOption('BadPosition', enumOptions)
            ]).then(function () {
                var badQCRecords = [];
                _.forEach(qcRecords, function (qcRecord) {
                    if (qcRecord.BadType !== undefined) {
                        badQCRecords.push({
                            BadType: enumOptions.BadType[qcRecord.BadType],
                            BadPosition: enumOptions.BadPosition[qcRecord.BadPosition],
                            Description: qcRecord.Description,
                            Images: qcRecord.Images
                        });
                    }
                });
                result.qcRecords = badQCRecords;
                deferred.resolve({
                    Data: result,
                    Error: null
                });
            }, function (err) {
                deferred.resolve({
                    Data: null,
                    Error: err
                });
            });
        });
    }

    return deferred.promise;
}

function queryExtendEnumOption (enumCode, target) {
    var deferred = Q.defer();

    extendEnumController.findEnumOptions(enumCode, function (err, option) {
        if (err) {
            deferred.reject(err);
            return;
        }
        target[enumCode] = option;
        deferred.resolve();
    });

    return deferred.promise;
}

function queryUserInfo (entityID, requiredRole) {
    var deferred = Q.defer();

    userController.getUserInfo(entityID, function (err, userRecord) {
        if (err) {
            deferred.reject({
                Data: null,
                Error: newErr
            });
            return;
        }
        if (!checkRoles(userRecord.Roles, requiredRole)) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.message = '您没有特裁权限，无法执行特裁业务。';
            deferred.reject({
                Data: null,
                Error: newErr
            });
            return;
        }
        var result = userRecord._doc;
        delete result.Roles;
        result.BarcodeType = BarcodeEnum.BarcodeType.Person;
        deferred.resolve({
            Data: userRecord,
            Error: null
        });
    });

    return deferred.promise;
}

function checkRoles (roles, roleCode) {
    var validate = false;
    for (var i = 0, len = roles.length; i < len; i++) {
        if (roles[i].Code === roleCode) {
            validate = true;
            break;
        }
    }
    return validate;
}

function queryHardwareInfo (terminalUniqueID) {
    var deferred = Q.defer();

    terminalController.findByUniqueID(terminalUniqueID, function (err, terminalRecord) {
        if (err) {
            deferred.reject(err);
            return;
        }
        if (terminalRecord == null) {
            var newErr = new Error();
            newErr.leval = 9;
            newErr.title = '查询终端错误';
            newErr.message = '请检查查询参数！';
            deferred.reject(newErr);
            return;
        }
        deferred.resolve({
            Terminal: terminalRecord._id,
            TerminalName: terminalRecord.Name
        });
    });

    return deferred.promise;
}

function writebizRecord (barcode, bizRecord) {
    var deferred = Q.defer();
    
    bizRecordController.insert(bizRecord, function (err, record) {
        if (err) {
            deferred.reject(err);
            return;
        }
        var uRecord = {
            Terminal: bizRecord.Terminal,
            TerminalName: bizRecord.TerminalName,
            Users: bizRecord.Users,
            BusinessStatus: bizRecord.BusinessStatus,
            QCStatus: bizRecord.QCStatus,
        };
        barcodeMasterController.updateByValue(barcode, uRecord, function (err, result) {
            if (err) {
                deferred.reject(err);
                return;
            }
            deferred.resolve(result);
        });
    });

    return deferred.promise;
}